home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
mg2a_src.zip
/
SYS
/
MSDOS
/
FILEIO.C~
< prev
next >
Wrap
Text File
|
1991-02-16
|
11KB
|
483 lines
/*
* Name: Mg 2a
* MSDOS file I/O (TurboC 1.5)
*/
#include "def.h"
#include <stdio.h>
#ifdef MSC
#include <dos.h>
#endif /* MSC */
#ifndef F_OK
#define F_OK 0
#define X_OK 1
#define W_OK 2
#define R_OK 4
#endif
#ifndef NO_DIR
extern char *wdir;
#endif
static FILE *ffp;
/*
* Open a file for reading.
*/
ffropen(fn)
char *fn;
{
if ((ffp=fopen(fn, "rb")) == NULL)
return (FIOFNF);
return (FIOSUC);
}
/*
* Open a file for writing.
* Return TRUE if all is well, and
* FALSE on error (cannot create).
*/
ffwopen(fn)
char *fn;
{
if ((ffp=fopen(fn, "wb")) == NULL) {
ewprintf("Cannot open file for writing");
return (FIOERR);
}
return (FIOSUC);
}
/*
* Close a file.
* Should look at the status.
*/
ffclose()
{
(VOID) fclose(ffp);
return (FIOSUC);
}
/*
* Write a line to the already
* opened file. The "buf" points to the
* buffer, and the "nbuf" is its length, less
* the free newline. Return the status.
* Check only at the newline.
*/
ffputline(buf, nbuf)
register char buf[];
{
register int i;
for (i=0; i<nbuf; ++i)
putc(buf[i]&0xFF, ffp);
putc('\r', ffp); /* MSDOS wants \r\n line seperators */
putc('\n', ffp);
if (ferror(ffp) != FALSE) {
ewprintf("Write I/O error");
return (FIOERR);
}
return (FIOSUC);
}
/*
* Write a buffer to the already
* opened file. bp points to the
* buffer. Return the status.
* Check only at the newline and
* end of buffer.
*/
ffputbuf(bp)
BUFFER *bp;
{
register char *cp;
register char *cpend;
register LINE *lp;
register LINE *lpend;
lpend = bp->b_linep;
lp = lforw(lpend);
do {
cp = <ext(lp)[0]; /* begining of line */
cpend = &cp[llength(lp)]; /* end of line */
while(cp != cpend) {
putc(*cp, ffp);
cp++; /* putc may evalualte arguments more than once */
}
lp = lforw(lp);
if(lp == lpend) break; /* no implied newline on last line */
putc('\r', ffp); /* MSDOS wants \r\n line seperators */
putc('\n', ffp);
} while(!ferror(ffp));
if(ferror(ffp)) {
ewprintf("Write I/O error");
return FIOERR;
}
return FIOSUC;
}
/*
* Read a line from a file, and store the bytes
* in the supplied buffer. Stop on end of file or end of
* line. Don't get upset by files that don't have an end of
* line on the last line; this seem to be common on CP/M-86 and
* MS-DOS. Delete any CR followed by a NL: This is the normal
* format for MS_DOS files, but also occurs when files are transferred
* from VMS or MS-DOS to Unix.
*/
ffgetline(buf, nbuf, nbytes)
register char buf[];
register int *nbytes;
{
register int c;
register int i;
i = 0;
for (;;) {
c = getc(ffp);
rescan:
if (c == '\r') { /* Delete any non-stray */
c = getc(ffp); /* carriage returns. */
if (c != '\n') {
buf[i++] = '\r';
if (i >= nbuf) return FIOLONG;
goto rescan;
}
}
if (c==EOF || c=='\n') /* End of line. */
break;
buf[i++] = c;
if (i >= nbuf) return FIOLONG;
}
if (c == EOF && ferror(ffp) != FALSE) {
ewprintf("File read error");
return FIOERR;
}
*nbytes = i;
return c==EOF ? FIOEOF : FIOSUC;
}
#ifndef NO_BACKUP
/*
* Rename the file "fname" into a backup copy.
* On Unix the backup has the same name as the
* original file, with a "~" on the end - unfortunately
* this does not map well to MS-DOS - the old .bak convention
* is used.
*/
fbackupfile(fname)
char *fname;
{
register char *nname, *ptr;
char *strchr();
if ((nname=malloc(strlen(fname)+3+1)) == NULL)
return (ABORT);
(void) strcpy(nname, fname);
if ((ptr = strchr(nname, '.')) != 0)
strcpy(ptr, ".bak");
else
strcat(ptr, ".bak");
if (strcmp(fname, nname) == 0) {
free(nname);
return FALSE;
}
(void) unlink(nname); /* Ignore errors. */
(void) rename(fname, nname);
free(nname);
return (TRUE);
}
#endif
/*
* The string "fn" is a file name.
* convert all filenames to lower case, and convert all '\\' characters
* to forward slashes. This is simply my preference, uppercase and
* back slashes are also viable.
*/
/*ARGSUSED*/
adjustmsdos(fn)
register char *fn;
{
register char c;
while ((c = *fn) != '0') {
if (ISUPPER(c))
*fn = TOLOWER(c);
if (c=='/')
*fn = '\\';
++fn;
}
}
#ifndef NO_STARTUP
#define STARTUPNAME ".mg"
/*
* find the users startup file, and return it's name. Check for
* if MGSTARTUP is defined, then use that. Otherwise, look
* for .mg in the current directory, then in the root directory.
*/
char *
startupfile()
{
register char *file;
static char temp[NFILEN];
char *getenv();
if ((file = getenv("MGSTARTUP")) != NULL )
{
if (access(file, F_OK) == 0)
return file;
return NULL;
}
if (access (STARTUPNAME, F_OK) == 0)
return STARTUPNAME;
strcpy(temp, "/");
strcat(temp, STARTUPNAME);
if (access (temp, F_OK) == 0)
return temp;
return NULL;
}
#endif
/*******************************************************************/
/* new stuff between release 1a and 2a */
/*******************************************************************/
/* convert all filenames to a canonical format, which in the case of
* MSDOS is X:/currentdir/filename. Note that each drive letter has
* it's OWN current directory, so if the user specifies a drive letter,
* we use that drive's current directory, not it's root.
*/
/* MSC doesn't have getdrive and getcurdir routines; simulate them.
* They are both pretty gross. Blame Microsoft */
#ifdef MSC
unsigned getdisk()
{
unsigned currentdrive;
_dos_getdrive(¤tdrive);
return currentdrive-1;
}
void getcurdir(unsigned drivenumber, char *buf)
{
unsigned currentdrive = getdisk()+1;
unsigned number_of_drives; /* unused */
static char bufr[NFILEN];
_dos_setdrive(drivenumber, &number_of_drives);
getcwd(&bufr[0], NFILEN-1);
_dos_setdrive(currentdrive, &number_of_drives);
strcpy(buf, &bufr[3]);
}
#endif
char *adjustname(fn)
register char *fn;
{
register char *cp;
static char fnb[NFILEN];
struct passwd *pwent;
cp = fnb;
/* handle A:foo\bar */
if (fn[0] && fn[1] == ':') {
*cp++ = *fn++;
*cp++ = *fn++;
*cp = '\0';
adjustmsdos(fnb); /* force case to lower */
if (*fn != '/' && *fn != '\\') {
*cp++ = '\\';
getcurdir(fnb[0]-'a'+1, cp);
cp = fnb + strlen(fnb);
}
else
*cp++ = *fn++;
}
/* handle \foo\bar */
else if (*fn == '/' || *fn == '\\') {
*cp++ = (char) (getdisk() + 'a');
*cp++ = ':';
*cp++ = *fn++;
}
else {
strcpy(fnb, wdir);
cp = fnb + strlen(fnb);
}
if(cp != fnb && cp[-1] != '/' && cp[-1] != '\\') *cp++ = '\\';
/* at this point, we should have a drive, and at least a single */
/* slash. Now copy over the rest of the filename, while handling */
/* certain pathalogical cases */
/* convert "//" to "/", "/./" to "/", and "/x/../" to "/" */
while(*fn) {
switch(*fn) {
case '.':
switch(fn[1]) {
case '\0':
*--cp = '\0';
adjustmsdos(fnb);
return fnb;
case '/':
case '\\':
fn += 2;
continue;
case '.':
if(fn[2]=='/' || fn[2]=='\\' || fn[2] == '\0') {
--cp;
while(cp > fnb && *--cp != '/' && *cp != '\\')
;
if (cp==fnb) cp += 2;
++cp;
if(fn[2]=='\0') {
*--cp = '\0';
adjustmsdos(fnb);
return fnb;
}
fn += 3;
continue;
}
break;
default:
break;
}
break;
case '/':
case '\\':
fn++;
continue;
default:
break;
}
while(*fn && (*cp++ = *fn++) != '/' && fn[-1] != '\\')
;
}
if (cp != fnb + 3 && cp[-1]=='\\') --cp;
*cp = '\0';
adjustmsdos(fnb);
return fnb;
}
#ifndef NO_DIRED
#include "kbd.h"
#define DIRFILE "_dirlist_.$$$"
BUFFER *dired_(dirnam